package com.wang.tool.invoker;


import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.BiFunction;
import java.util.function.Supplier;

/**
 * @Description 异步执行器
 * @Author shaopeng
 * @Date 2021/9/10
 * @Version 1.0
 */
public class AsyncInvoker {

    /**
     * 异步执行,有回调
     *
     * @param supplier 业务
     * @param executor 线程池 非空
     * @param handle 结果处理器
     * @return
     */
    public static <R> CompletableFuture<R> async(Executor executor, Supplier<R> supplier, BiFunction<R, Throwable, R> handle) {
        if (executor == null) {
            throw new IllegalArgumentException("executor can not be null");
        }
        if (supplier == null) {
            throw new IllegalArgumentException("supplier can not be null");
        }
        CompletableFuture<R> future ;
        try {
            future = CompletableFuture.supplyAsync(supplier, executor);
        } catch (Throwable e) {
            future = new CompletableFuture<>();
            future.completeExceptionally(new RuntimeException(e));
        }
        if (handle != null) {
            return future.handle((result, throwable) -> {
                if (throwable != null) {
                    throwable = throwable.getCause();
                }
                return handle.apply(result, throwable);
            });
        }
        return future;
    }


}
